Skip to content

Phase 2C: generate the SDK wire types from a Rust emitter#559

Merged
MGudgin merged 2 commits into
mainfrom
user/gudge/versioning_phase2c_optC_rustemit
Jun 26, 2026
Merged

Phase 2C: generate the SDK wire types from a Rust emitter#559
MGudgin merged 2 commits into
mainfrom
user/gudge/versioning_phase2c_optC_rustemit

Conversation

@MGudgin

@MGudgin MGudgin commented Jun 24, 2026

Copy link
Copy Markdown
Member

Summary

Phase 2C of the versioning remediation. Closes the third drift surface - the Rust wire model, the generated JSON schema, and the SDK TypeScript types - by emitting the SDK wire types from a hand-written Rust emitter (wxc_common::ts_emit, exposed via mxc_schema_gen --ts) with no new npm or cargo dependency, asserting the hand-written public types conform to them, and retiring the hand-maintained 0.5.0-alpha-strict stable schema view.

A wire-model change now ripples to all three surfaces or fails CI; it cannot drift silently.

What changed

  • Rust emitter src/core/wxc_common/src/ts_emit.rs walks the generated schema value and emits sdk/src/generated/wire.ts (an internal drift oracle, not public API). wire.rs is refactored to share a schema_value() helper; the JSON schema output stays byte-for-byte identical.
  • mxc_schema_gen --ts mode emits the committed TS; the existing schema mode is unchanged.
  • Conformance test sdk/tests/unit/wire-conformance.test.ts asserts (at tsc time) that sdk/src/types.ts conforms to the generated wire shape - bidirectional and exact: catches public/wire field rename/removal, wire-only field additions the SDK forgot to expose, and enum narrowing and widening, at the root and every leaf. Every intentional divergence is pinned to a documented allow-list.
  • CI gate scripts/versioning/check-sdk-types-codegen.js runs the emitter and diffs the committed wire.ts (mirrors check-schema-codegen.js); wired into the Versioning Checks job.
  • Retires schemas/stable/mxc-config.schema.0.5.0-alpha-strict.json and updates the three doc references.

Review

Converged through two independent, model-diverse adversarial review loops (GPT-5.3-Codex and GPT-5.5) before this PR; the bidirectional/exact conformance design is the result of findings from both.

Verification

  • cd sdk && npm test -> 181 pass (incl. the conformance oracle)
  • cargo test -p wxc_common --features schema-gen ts_emit -> 3 pass; clippy + fmt clean
  • node scripts/versioning/check-sdk-types-codegen.js -> OK
  • node scripts/versioning/check-schema-codegen.js -> OK (schema byte-identical)
  • node scripts/versioning/validate-configs.js -> 169/169

Follow-up (non-blocking)

A companion conformance block for the state-aware public types (sdk/src/state-aware-types.ts vs the IsolationSession* wire defs), flagged by both reviewers.

Microsoft Reviewers: Open in CodeFlow

Copilot AI review requested due to automatic review settings June 24, 2026 19:00
@MGudgin MGudgin requested a review from a team as a code owner June 24, 2026 19:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Phase 2C of the versioning remediation: this PR eliminates the remaining “drift surface” between the Rust wire model, the generated JSON schema, and the SDK TypeScript wire types by generating sdk/src/generated/wire.ts via a hand-written Rust emitter (invoked as mxc_schema_gen --ts) and enforcing conformance in CI and unit tests.

Changes:

  • Add a Rust TypeScript emitter (wxc_common::ts_emit) and expose TS emission via mxc_schema_gen --ts.
  • Add a compile-time conformance oracle test in the SDK plus a CI codegen gate to prevent wire.ts drift.
  • Retire the legacy hand-maintained 0.5.0-alpha-strict stable schema view and update docs accordingly.
Show a summary per file
File Description
src/tools/mxc_schema_gen/src/main.rs Adds --ts mode and refactors output handling for schema vs TS emission.
src/core/wxc_common/src/wire.rs Factors out shared schema_value() and adds generate_sdk_types_ts() entrypoint for TS emission.
src/core/wxc_common/src/ts_emit.rs New Rust emitter that walks the schema Value and emits deterministic wire.ts.
src/core/wxc_common/src/lib.rs Exposes ts_emit behind the schema-gen feature.
sdk/tests/unit/wire-conformance.test.ts New compile-time (tsc) conformance oracle between public SDK types and generated wire types.
sdk/src/generated/wire.ts New generated drift-oracle TypeScript wire types (committed output).
sdk/README.md Removes references to the retired 0.5.0-alpha-strict schema view.
sdk/package.json Adds the new wire conformance unit test to the unit test run list.
scripts/versioning/check-sdk-types-codegen.js New CI gate to regenerate wire.ts and diff against committed output (with CRLF/LF normalization).
schemas/stable/mxc-config.schema.0.5.0-alpha-strict.json Deletes the hand-maintained strict stable schema view.
docs/schema-codegen.md Documents the new generated SDK wire-types drift oracle and updated roadmap.
.github/workflows/Versioning.Checks.Job.yml Wires the new SDK wire-types codegen gate into Versioning Checks.
.github/copilot-instructions.md Updates repo conventions to reflect removal of -strict stable schemas and addition of generated SDK wire types.

Copilot's findings

  • Files reviewed: 12/13 changed files
  • Comments generated: 2

Comment thread src/core/wxc_common/src/ts_emit.rs Outdated
Comment thread .github/workflows/Versioning.Checks.Job.yml Outdated
@MGudgin

MGudgin commented Jun 24, 2026

Copy link
Copy Markdown
Member Author

Addressed both review comments in 74a22c0 (doc/label accuracy, no behavior change):

  • ts_emit.rs module doc reworded so the serde_json::Value is described as built from the MxcConfig wire model (the same value generate_config_schema_json renders to JSON text), not produced by that String-returning function.
  • Versioning Checks step renamed to ...in sync with the Rust wire model... to match the sibling schema-codegen step and reflect that the gate regenerates wire.ts from the wire model via mxc_schema_gen --ts.

@bbonaby

bbonaby commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

To generate typescript types from the rust types should we be using https://crates.io/crates/ts-rs ?

@MGudgin MGudgin force-pushed the user/gudge/versioning_phase2c_optC_rustemit branch from 74a22c0 to 122aa69 Compare June 25, 2026 04:17
@MGudgin MGudgin changed the base branch from main to user/gudge/versioning_phase2b June 25, 2026 04:17
@MGudgin MGudgin force-pushed the user/gudge/versioning_phase2c_optC_rustemit branch 2 times, most recently from c2fa61b to ab4b36b Compare June 25, 2026 16:49
Comment thread schemas/stable/mxc-config.schema.0.5.0-alpha-strict.json
Comment thread scripts/versioning/check-sdk-types-codegen.js Outdated
Comment thread sdk/src/generated/wire.ts
Comment thread docs/schema-codegen.md
Base automatically changed from user/gudge/versioning_phase2b to main June 26, 2026 15:03
This PR changes the SDK's wire TypeScript types to be generated from the Rust
wire model by a hand-written emitter (no third-party generator), guarded by a
conformance test and a CI gate so they cannot drift, and retires the
hand-maintained 0.5.0-alpha-strict stable schema view. This closes the third
versioning drift surface: a wire-model change ripples to the Rust model, the JSON
schema, and the SDK types, or it fails CI.

Details:
- Add wxc_common::ts_emit, a Rust emitter that walks the generated schema value
  and emits TypeScript (string-union enums, closed/open objects, $ref,
  anyOf [T, null], arrays, scalars). Refactor wire.rs so the JSON-schema renderer
  and the new generate_sdk_types_ts() share a schema_value() helper; the JSON
  schema output stays byte-for-byte identical.
- Add a --ts mode to mxc_schema_gen that emits the committed
  sdk/src/generated/wire.ts (an internal drift oracle, not public API).
- Add sdk/tests/unit/wire-conformance.test.ts: compile-time assertions that
  sdk/src/types.ts conforms to the generated wire shape - bidirectional and exact
  (public/wire field rename/removal, wire-only field additions, and enum
  narrowing and widening), at the root and every leaf, with each intentional
  divergence pinned to a documented allow-list.
- Add scripts/versioning/check-sdk-types-codegen.js, a CI gate that runs the
  emitter and diffs the committed wire.ts (mirrors check-schema-codegen.js); wire
  it into the Versioning Checks job. No new npm or cargo dependency.
- Retire schemas/stable/mxc-config.schema.0.5.0-alpha-strict.json and update the
  doc references (sdk/README.md, docs/schema-codegen.md, copilot-instructions.md).

Tests:
- cargo test --workspace; cargo fmt --all -- --check; cargo clippy --workspace
  --all-targets -- -D warnings; ts_emit unit tests.
- Schema codegen, SDK wire-types codegen, and config corpus (169/169) gates.
- cd sdk && npm test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Generated-with: claude-opus-4.8
@MGudgin MGudgin force-pushed the user/gudge/versioning_phase2c_optC_rustemit branch from ab4b36b to b529476 Compare June 26, 2026 15:24
…atives)

This PR addresses two review comments from bbonaby on the 2C PR (#559):

Details:
- Reword the header comment in check-sdk-types-codegen.js to drop the internal
  "Phase 2C, option C" / "options A/B" vocabulary, matching the repo convention
  of keeping phase/spike naming out of shipped files. It now just describes what
  the gate does.
- Add an "Alternatives considered" subsection to docs/schema-codegen.md
  explaining why the SDK wire types use a hand-written Rust emitter (drift
  oracle) rather than generating the public API directly or using a third-party
  schema->TS generator, plus a note on the FlatBuffers option. Makes the
  rationale discoverable for future readers.

Tests:
- node scripts/versioning/check-sdk-types-codegen.js (gate still green;
  docs/comment-only change, generated wire.ts unaffected).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Generated-with: claude-opus-4.8
@MGudgin MGudgin merged commit fd95b47 into main Jun 26, 2026
18 checks passed
@MGudgin MGudgin deleted the user/gudge/versioning_phase2c_optC_rustemit branch June 26, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants